package queue;

import java.util.Scanner;

public class circleArrQueue {
    public static void main(String[] args) {
        // 测试环形队列的主要功能
        int maxSize = 4; // 因为环形队列约定要空出一个位置来（rear表示最后一个元素的后一个位置），所以取4相当于刚才的3
        circleQueue aq = new circleQueue(maxSize);
        Scanner sc = new Scanner(System.in);
        boolean loop = true;
        while (loop) {
            System.out.println("请根据提示输入字母：");
            System.out.println("a(add) ---> 表示向环形队列中添加元素");
            System.out.println("g(get) ---> 表示取出环形队列中的元素");
            System.out.println("s(scan) ---> 表示浏览环形队列中现有的元素");
            System.out.println("h(head) ---> 表示查看当环形前队列的头元素");
            System.out.println("e(exit) ---> 表示退出当前程序");
            String in = sc.next();
            switch (in) {
                case "a" :
                    System.out.println("输入要添加的数字：");
                    int numIn = sc.nextInt();
                    aq.addElement(numIn);
                    break;
                case "g" :
                    System.out.println(aq.getElement());
                    break;
                case "s" :
                    aq.printAllElement();
                    break;
                case "h" :
                    System.out.println(aq.head());
                    break;
                case "e" :
                    return;
                default:
                    continue;
            }
        }
    }
}


// 环形队列都要考虑取余
class circleQueue {
    private int maxSize; // 表示队列的最大容量
    private int front; // 队列头
    private int rear; // 队列尾部
    private int[] arr; // 该数组用于存放数据,模拟队列

    public circleQueue (int maxSize) {
        this.maxSize = maxSize;
        arr = new int[maxSize];
        front = 0; // 在环形队列中让front指向队列的第一个元素
        rear = 0; // rear指向队列的最后一个元素的后一个位置，因为是希望空出一个空间，作为约定
    }

    // 判断环形队列是否为满
    public boolean isFull () {
        return (rear + 1) % maxSize == front;
    }

    // 向环形队列中添加一个元素
    public void addElement (int element) {
        // 首先要判断队列是否满了
        if (isFull()) {
//            throw new RuntimeException("队列已满，无法添加元素！"); // throw一个问题就直接终止程序
            System.out.println("队列已满，无法添加元素！");
            return;
        }
        arr[rear] = element; // rear本身就指向最后一个元素的后一位置，所以直接赋值
        rear = (rear + 1) % maxSize; // 注意考虑取余
    }

    // 判断环形队列是否为空
    public boolean isEmpty () {
        return rear == front;
    }

    // 取出队列中的一个元素
    public int getElement () {
        // 首先要判断队列是否为空
        if (isEmpty()) {
            throw new RuntimeException("队列为空不能取出元素！");
        }
        int tmp = arr[front];
        front = (front + 1) % maxSize;
        return tmp;
    }

    // 求队列中此时有效元素的个数
    public int size () {
        return (rear - front + maxSize) % maxSize;
    }
    // 显示队列中的所有数据
    public void printAllElement () {
        // 判断当前队列是否为空
        if (isEmpty()) {
            System.out.println("当前队列为空~~");
            return;
        }
        for (int i = front; i < front + size(); i++) { // i < front + 队列中有效元素的个数
            // 此时i一直加加势必会越界，所以不能用i来访问队列
            System.out.printf("arr[%d] = " + arr[i % maxSize] + "\n" , i % maxSize);
        }
    }

    // 查看队列当前的头元素
    public int head () {
        return arr[front];
    }
}
